# encoding: utf-8
"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '11/05/2025'
    comment: app初始化
"""
import os
from fastapi import APIRouter, FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
from importlib import import_module
from inspect import getmembers
from fastapi.middleware.cors import CORSMiddleware  # 添加这行
from fastapi.templating import Jinja2Templates

from project.output.docx import DOCX_FOLDER
from project.templates import TEMPLATES_FOLDER


def init_app():
    """
    :return:
    """
    app = FastAPI(title='Interview Design')

    # 模板配置
    templates = Jinja2Templates(directory=TEMPLATES_FOLDER)

    # 页面路由
    @app.get("/", response_class=HTMLResponse, include_in_schema=False)
    async def index(request: Request):
        """首页"""
        return templates.TemplateResponse("index.html", {"request": request})

    # 页面路由
    @app.get("/room", response_class=HTMLResponse, include_in_schema=False)
    async def room(request: Request):
        """房间"""
        room = dict(request.query_params)

        context = {
            "request": request,
            "room": room
        }

        return templates.TemplateResponse("room.html", context)

    # word路径映射
    app.mount("/docx", StaticFiles(directory=DOCX_FOLDER), name="docx")
    app.mount("/static", StaticFiles(directory=TEMPLATES_FOLDER), name="static")

    # 添加 CORS 中间件
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],  # 在生产环境中应该指定具体域名
        allow_credentials=True,
        allow_methods=["*"],  # 允许所有方法
        allow_headers=["*"],  # 允许所有头部
    )

    # view层 api register router
    blue_prints = get_models('project.api', lambda x: isinstance(x, APIRouter))
    for blue_print in blue_prints:
        app.include_router(blue_print)

    return app


def get_modules(package_name: str) -> list[str]:
    """获取包名下所有非__init__的模块名
    :param: package_name: 指定包名(含导入路径名)
    """
    package = import_module(package_name)
    path_name = package.__path__[0]
    files = os.listdir(path_name)
    modules = []
    for file in files:
        if file.startswith("__"):
            continue
        if os.path.isfile(f"{path_name}/{file}"):
            if not file.endswith(".py"):
                continue
            name, _ = os.path.splitext(file)
            if not package_name:
                modules.append(name)
            else:
                modules.append(f"{package_name}.{name}")
        else:
            modules.extend(get_modules(package_name=f"{package_name}.{file}"))

    return modules


def get_models(package_name: str, predicate=None) -> list:
    """获取包名下所有指定类
    :param: package_name: 指定包名(含导入路径名)
    """
    modules = get_modules(package_name)
    ret_models = []
    for module in modules:
        _module = import_module(module)
        ret_models.extend(getmembers(_module, predicate))

    return [v for _, v in ret_models]
